Skip to content

Agents: a conversation this agent cannot read fails for good; examples of unique names; no Pydantic AI banner - #303

Merged
igalshilman merged 5 commits into
mainfrom
agents-real-model-fixes
Nov 9, 2026
Merged

igalshilman merged 5 commits into
mainfrom
agents-real-model-fixes

Conversation

@igalshilman

@igalshilman igalshilman commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Found by running the agent examples against a real model (OpenAI) and Restate 1.8.1, with one Restate server, as the examples' README suggests.

  • A conversation this agent cannot read fails for good, not retried forever. router.py's desk, registered after create_agent.py's desk, loaded desk/alice's LangGraph conversation as Pydantic AI messages: a ValidationError, which Restate retried with backoff for good, as every attempt read the same row. Every load of a stored item now goes through load_item, which fails with a terminal error: "This conversation holds a message that this agent cannot read (stored by an agent of another framework under the same name, or by another version of its framework?): ...". A version of a framework that stores its messages differently now fails a request at once too, rather than retrying it until a rollback: a retrying invocation holds the key, and every message after it waited behind it. tests/agents_conversation.py tests the terminal error (it fails without the fix). Checked live, one framework's conversation read by another's agent: into Pydantic AI or LangGraph, chat and messages fail at once, with no invocation left retrying. Into OpenAI, whose items are any JSON, the load succeeds; the provider refuses the foreign messages, and the turn ends refused, as before.
  • No two examples serve one name. The basic agents are openai_assistant, pydantic_ai_assistant, langgraph_assistant and adk_assistant (all four were assistant); router.py's desk is front_desk, loop.py's refunds is refund_loop, and create_agent.py's orders service is shipping. The tutorial's lessons, one application, keep wallet.
  • Pydantic AI: no first-run banner. Pydantic AI prints a banner on a process's first agent run unless an installed package started it; a turn starts in a Restate handler, behind the event loop, where it cannot tell, so every server printed it. restate.agents.pydantic_ai sets pydantic_ai.BANNER_ENABLED = False, as Pydantic AI advises a library that runs agents on its users' behalf.

Checked with a real model: every agent example but adk_agent.py (no Gemini key), with the commands its comment lists: tool calls, signals (support, refund_graph, loop), the three-framework team, triage's review, a delayed follow-up; a crash of support.py while it waited for an approval resumed with each tool call made once.

Checks: ruff format --check, ruff check, pyright and mypy, and pytest tests/* (561 passed) locally, before the test.

Pydantic AI prints a banner on a process's first agent run unless an
installed package started it. A turn starts in a Restate handler, behind
the event loop, where it cannot tell, so every server printed it. Turn it
off with pydantic_ai.BANNER_ENABLED, as Pydantic AI advises a library that
runs agents on its users' behalf.
Restate keeps a key's state, its database with it, when another example
is registered: router.py's desk loaded create_agent.py's LangGraph
conversation, failed to read it, and was retried for good. The basic
agents are openai_assistant, pydantic_ai_assistant, langgraph_assistant
and adk_assistant; router.py's desk is front_desk, loop.py's refunds is
refund_loop, and create_agent.py's orders service is shipping. A test
fails when two examples serve a name; the tutorial's lessons, one
application, share theirs.
…ried forever

A stored row that the agent's framework cannot load (one stored by an
agent of another framework, under the same name) failed the handler with
the framework's own error, and Restate retried it for good: every
attempt read the same row. Every load of a stored item now goes through
load_item, which fails with a terminal error that says so.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues — one small suggestion inline.

Reviewed changes

I reviewed all 4 commits: the terminal failure for stored items an agent cannot read, the renamed examples, and the Pydantic AI banner switch.

  • load_item: wraps Items.load and turns any parse failure into a TerminalError. Every former items.load(...) call in python/restate/agents/ now goes through it, and a grep finds no direct calls left. Each framework's load is a deterministic parse, so a retry could never succeed. In answer_once, Conversation.load runs before anything is written, so the failure leaves no half-stored turn.
  • Unique example names: across examples-agents/, each example now serves its own names. The only shared name is the tutorial's wallet, which is intentional. create_agent.py's service no longer collides with support.py's orders, and the curl lines, docstrings and tests/examples_agents.py all match.
  • pydantic_ai.BANNER_ENABLED = False: the flag exists from pydantic-ai-slim>=2.66.0, the pinned minimum, and _display._banner_suppressed reads it on each call. So setting it at import takes effect.

ℹ️ A framework upgrade that changes the stored format now fails for good too

load_item cannot tell another framework's row apart from a row this agent wrote under an older version of its own framework. Before this PR, a schema change in a pydantic-ai/ADK upgrade kept the invocation retrying, so pinning back or deploying a fix let it recover. Now it fails at once. The error text, which suggests another framework, would also point the wrong way in that case. This is a reasonable trade-off. It is noted here so it is a deliberate choice; a release note might be worth it.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using claude-opus-5-5 | 𝕏

Comment thread python/restate/agents/_conversation.py Resolved
@github-actions

github-actions Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Test Results

  8 files  ±0    8 suites  ±0   3m 52s ⏱️ -20s
 71 tests ±0   71 ✅ ±0  0 💤 ±0  0 ❌ ±0 
322 runs  ±0  322 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit da14dce. ± Comparison against base commit 9ec3c60.

♻️ This comment has been updated with latest results.

…r version of its framework too, and a test

From the review of #303: load_item cannot tell another framework's row
from one stored by another version of the agent's own framework, so the
error says either. A test of the terminal error: an agent of another
framework, under the same name, fails for good.
@igalshilman

Copy link
Copy Markdown
Contributor Author

On the format change in a framework's upgrade: kept as a terminal error, a deliberate choice. A retrying invocation holds the key, so every message after it waited behind it until a rollback; now a request fails at once, and the stored rows are left as they are, so the next message after a fix is answered. The error now names that case too (da14dce).

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found. Both points from the last review are covered.

Reviewed changes

I reviewed the one commit added since the last review (da14dce).

  • Broadened the load_item error and docstring: they now name "another version of its framework" as well as another framework. This covers the upgrade case the last review raised, so the message no longer points the wrong way.
  • Added test_a_conversation_this_agent_cannot_read_fails_for_good: it stores a turn with the test Items, then reads it with an Items subclass that rejects those rows, and checks for a TerminalError that carries the original ValueError. The test passes locally.

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

@igalshilman
igalshilman merged commit 56e0a86 into main Nov 9, 2026
12 checks passed
@igalshilman
igalshilman deleted the agents-real-model-fixes branch November 9, 2026 11:44
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 9, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant